#!/bin/bash
set -e

bindir="$HOME/.earthly"
if [ ! -d "$bindir" ]; then
  mkdir -p "$bindir"
fi

# get_realpath implements "readlink -f" for both Linux and MacOX (MacOS does not support readlink -f)
function get_realpath() {
    TARGET_FILE="$1"
    cd "$(dirname "$TARGET_FILE")"
    TARGET_FILE=$(basename "$TARGET_FILE")
    while [ -L "$TARGET_FILE" ]
    do
        TARGET_FILE=$(readlink "$TARGET_FILE")
        cd "$(dirname "$TARGET_FILE")"
        TARGET_FILE=$(basename "$TARGET_FILE")
    done
    PHYS_DIR="$(pwd -P)"
    RESULT="$PHYS_DIR/$TARGET_FILE"
    echo "$RESULT"
}

scriptname=$(basename "$0")
scriptpath=$(get_realpath "$0")
script_dir="$( cd "$( dirname "$scriptpath" )" &> /dev/null && pwd )"

last_check_state_path=/tmp/last-earthly-prerelease-check
last_flag_hash_path=/tmp/last-earthly-flag-hash

detect_frontend() {
  if which docker; then
    return
  elif which podman; then
    return
  fi

  echo "none"
}

frontend_bin=$(detect_frontend)

get_latest_binary() {
    $frontend_bin rm --force earthly_binary 2>/dev/null >&2 || true

    $frontend_bin pull docker.io/earthly/earthlybinaries:prerelease >&2
    $frontend_bin create --name earthly_binary docker.io/earthly/earthlybinaries:prerelease >&2

    earth_bin_path=/earthly-linux-amd64
    bk_platform=linux/amd64
    if [ "$(uname)" == "Darwin" ]; then
        if [ "$(uname -m)" == "arm64" ]; then
            earth_bin_path=/earthly-darwin-arm64
            bk_platform=linux/arm64
        else
            earth_bin_path=/earthly-darwin-amd64
        fi
    fi

    $frontend_bin pull --platform="$bk_platform" docker.io/earthly/buildkitd:prerelease >&2
    $frontend_bin cp earthly_binary:"$earth_bin_path" "$bindir/earthly-prerelease" >&2
    $frontend_bin rm earthly_binary >&2
}

do_reset() {
    rm -f "$last_check_state_path"
    $frontend_bin stop earthly-buildkitd || true
    $frontend_bin rm -f earthly-buildkitd || true
    rm -f "$bindir/earthly-prerelease"
    $frontend_bin rm --force earthly_binary 2>/dev/null || true
    $frontend_bin rmi -f docker.io/earthly/buildkitd:prerelease || true
    $frontend_bin rmi -f docker.io/earthly/earthlybinaries:prerelease || true
}


do_upgrade() {
    do_reset
    get_latest_binary
}

do_help() {
    if ! command -v "$bindir/earthly-prerelease"; then
        get_latest_binary
    fi

    echo "------------------- earthly prerelease script help -------------------"
    echo "NAME:"
    echo "   $scriptname - A wrapper around the earthly binary that checks for updates once an hour"
    echo ""
    echo "COMMANDS:"
    echo "   reset     Removes prerelease binary and associated docker containers"
    echo "   upgrade   Forces a new check for the latest version"
    echo ""
    echo ""
    echo "---------------------------- earthly help -----------------------------"
    exec -a "$scriptname" "$bindir/earthly-prerelease" --help
}

case "$1" in
    reset)
        do_reset
        ;;

    upgrade)
        do_upgrade
        ;;

    -h)
        do_help
        ;; # using a ;& fallthrough won't work on macOS
    --help)
        do_help
        ;;

    *)
        last=$(cat "$last_check_state_path" 2>/dev/null || echo 0)
        now=$(date +%s)
        since=$(( now - last ))

        earthly_version_flag_overrides_path="$script_dir/.earthly_version_flag_overrides"

        last_flag_hash=$(cat "$last_flag_hash_path" 2>/dev/null || echo null)
        flagoverride_hash=$(md5sum "$earthly_version_flag_overrides_path" | awk '{print $1}')
        if [ -z "$COMP_LINE" ]; then
            update="false"
            if [ "$last_flag_hash" != "$flagoverride_hash" ]; then
                echo ".earthly_version_flag_overrides has changed since last run, checking for prerelease binaries" \
                     "If you see an \"unable to set <flag-name>: invalid flag\" error, you may have to wait for the" \
                     "prerelease binary to be built by GHA on the main branch, before re-attempting a ./earthly upgrade" | fold >&2
                update="true"
            elif [ "$since" -ge 3600 ]; then
                echo "checking for latest earthly prerelease binaries" >&2
                update="true"
            fi

            if [ "$update" = "true" ] && [ "$EARTHLY_DISABLE_AUTO_UPDATE" != "true" ]; then
                get_latest_binary
                echo "Updated prerelease binary. Version:" >&2
                "$bindir/earthly-prerelease" --version >&2
                echo "$now" >"$last_check_state_path"
                echo "$flagoverride_hash" >"$last_flag_hash_path"
            fi

        fi

        EARTHLY_VERSION_FLAG_OVERRIDES="$(tr -d '\n' < "$earthly_version_flag_overrides_path")"
        export EARTHLY_VERSION_FLAG_OVERRIDES
        exec -a "$scriptname" "$bindir/earthly-prerelease" "$@"
        ;;
esac
